import { OVERRIDE_METHOD_METADATA } from '@dataui/crud/constants';
import { CrudRoutesFactory, R, Swagger } from '@dataui/crud/crud';
import { BaseRouteName } from '@nest-crud/crud';
import { isNil, isObject, objKeys } from '@nest-crud/utils';
import { HttpStatus } from '@nestjs/common';
import { CRUD_BASE_CONTROLLER_MD, IS_BASE_METHOD_MD, NO_MERGE_BASE_MD } from '../constants';

export class CrudPlusRoutesFactory extends CrudRoutesFactory {
  protected override setSwaggerResponseOk(name: BaseRouteName): void {
    const override = R.getOverrideRoute(this.targetProto[name]);
    if (!override || !Swagger.getResponseOk(this.targetProto[name])[HttpStatus.OK]) {
      super.setSwaggerResponseOk(name);
    }
  }
  protected override getManyBase(name: BaseRouteName): void {
    if (!this.targetProto[name]) {
      super.getManyBase(name);
      return;
    }
    // eslint-disable-next-line no-self-assign
    this.targetProto[name] = this.targetProto[name];
    Reflect.defineMetadata(OVERRIDE_METHOD_METADATA, name, this.targetProto[name]);
    const isBase = R.get(IS_BASE_METHOD_MD, this.targetProto[name]);
    // console.log('isBase', isBase);
    if (isBase) return;
    const CrudOverrideData = R.get(CRUD_BASE_CONTROLLER_MD, this.target)?.[name];
    if (CrudOverrideData) {
      const CrudOverrideNoMerge: string[] | undefined = CrudOverrideData[NO_MERGE_BASE_MD];
      // console.log('overridedd4 CrudOverrideNoMerge', CrudOverrideData, CrudOverrideNoMerge);

      objKeys(CrudOverrideData).forEach((key) => {
        if (key == NO_MERGE_BASE_MD) return;
        const dataBase = CrudOverrideData[key];
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const dataNow: any = R.get(key, this.targetProto[name]);
        // [ ]支持移除
        // [ ]支持反向设置的不合并
        if (isNil(dataNow)) {
          // 新数据不为空
          R.set(key, dataBase, this.targetProto[name]);
        } else if (!isObject(dataBase) || !isObject(dataNow) || CrudOverrideNoMerge?.includes(key)) {
          R.set(key, dataNow, this.targetProto[name]);
        } else {
          R.set(key, { ...dataBase, ...dataNow }, this.targetProto[name]);
        }
        // console.log('overridedd3', key, dataBase, '-', dataNow);
      });
    }
  }
}
